﻿Imports System.Text
Imports System.IO
Imports System.Text.RegularExpressions
Imports System.Configuration

Public Class cTools


    Public Shared Function sFileReader() As String

        sFileReader = String.Empty
        Dim ofd As New OpenFileDialog()
        ofd.InitialDirectory = "C:\Users\vmware\Downloads"
        ofd.Filter = _
            "TXTファイル(*.txt)|*.txt|すべてのファイル(*.*)|*.*"
        ofd.FilterIndex = 0
        ofd.Title = "開くファイルを選択してください"
        ofd.RestoreDirectory = True
        ofd.CheckFileExists = True
        ofd.CheckPathExists = True

        If ofd.ShowDialog() = DialogResult.OK Then

            Dim sr As New StreamReader(ofd.FileName, cEPUB.ENC)
            sFileReader = sr.ReadToEnd()
            sr.Close()

        End If

    End Function


    Public Shared Function listNav_SE(str As String, s As String, e As String, ByVal bHasSE As Boolean) As List(Of String)

        listNav_SE = New List(Of String)

        Dim sPattern As String = "(?<=(" & s & "))[.\s\S]*?(?=(" & e & "))"

        Dim matches As MatchCollection = Regex.Matches(str, sPattern)
        For Each match As Match In matches

            If bHasSE Then
                listNav_SE.Add(s & match.Value & e)
            Else
                listNav_SE.Add(match.Value)
            End If

        Next

    End Function


    Public Shared Sub CopyDirectory( _
        ByVal sourceDirName As String, _
        ByVal destDirName As String)
        'コピー先のディレクトリがないときは作る
        If Not System.IO.Directory.Exists(destDirName) Then
            System.IO.Directory.CreateDirectory(destDirName)
            '属性もコピー
            System.IO.File.SetAttributes(destDirName, _
                System.IO.File.GetAttributes(sourceDirName))
        End If

        'コピー先のディレクトリ名の末尾に"\"をつける
        If destDirName.Chars((destDirName.Length - 1)) <> _
                System.IO.Path.DirectorySeparatorChar Then
            destDirName = destDirName + System.IO.Path.DirectorySeparatorChar
        End If

        'コピー元のディレクトリにあるファイルをコピー
        Dim fs As String() = System.IO.Directory.GetFiles(sourceDirName)
        Dim f As String
        For Each f In fs
            System.IO.File.Copy(f, _
                destDirName + System.IO.Path.GetFileName(f), True)
        Next

        'コピー元のディレクトリにあるディレクトリをコピー
        Dim dirs As String() = System.IO.Directory.GetDirectories(sourceDirName)
        Dim dir As String
        For Each dir In dirs
            CopyDirectory(dir, destDirName + System.IO.Path.GetFileName(dir))
        Next
    End Sub



End Class


Public Class cEPUB

    Public Shared encShift_JIS As Encoding = Encoding.GetEncoding("Shift_JIS")
    Public Shared encGB2321 As Encoding = Encoding.GetEncoding("gb2312")
    Public Shared encUTF8 As Encoding = Encoding.GetEncoding("utf-8")
    Public Shared sOutPutPathFolder As String = ConfigurationManager.AppSettings("OutPutPath") & Date.Now.ToString("yyyyMMdd") & "\"
    Public Shared sOutPutPathEpub As String = sOutPutPathFolder & "OEBPS" & "\"
    Public Shared sGUID As String = Guid.NewGuid().ToString()



    Public Shared ENC As Encoding = encGB2321
    Public Shared sBookName As String = "Title"
    Public Shared sCreator As String = "Creator"
    Public Shared sFileNB As String = "LW_"
    Public Shared sLang As String = "zh"



    Public Shared dPlayID As Decimal = 1
    Public Shared dSectionID As Decimal = 1
    Public Shared dChapterID As Decimal = 1
    Public Shared dAfterWordID As Decimal = 1


    Public Shared lOPF As New List(Of String)

    Public Shared cfMain As cFile
    Public Shared cfNav As cFile
    Public Shared cfOPF As cFile
    Public Shared cfNCX As cFile


    Public Shared Sub StartEpub()

        CreateFolder(sOutPutPathFolder)
        cTools.CopyDirectory(System.Windows.Forms.Application.StartupPath & "\Files\", sOutPutPathFolder)
        cfMain = New cFile("Main.html", "Main.html", sOutPutPathEpub & "Main.html", sBookName & "  " & sCreator)
        cfNav = New cFile("Nav.html", "Nav.html", sOutPutPathEpub & "Nav.html", "目录树")
        cfOPF = New cFile("content.opf", "content.opf", sOutPutPathEpub & "content.opf", "content.opf")
        cfNCX = New cFile("toc.ncx", "toc.ncx", sOutPutPathEpub & "toc.ncx", "toc.ncx")


        cfMain.sbText.Append(htmlBodyStart1)
        cfMain.sbText.Append(htmlAddTitle(cfMain.sTitle))

        cfNav.sbText.Append(htmlBodyStart1)
        cfNav.sbText.Append(htmlAddTitle(cfNav.sTitle))
        cfNav.sbText.Append(htmlAddBookList("主目录", "Main.html"))


        cfNCX.sbText.Append(ncxMapStart())
        cfNCX.sbText.Append(ncxNavPointAdd("主目录", "Main.html"))
        cfNCX.sbText.Append(ncxNavPointEnd())


        cfOPF.sbText.Append(opfPackageStart())
        cfOPF.sbText.Append(opfManifestStart())


    End Sub

    Public Shared Sub EndEpub()

        cfMain.sbText.Append(cEPUB.htmlBodyEnd())
        cfNav.sbText.Append(cEPUB.htmlBodyEnd())
        cfNCX.sbText.Append(cEPUB.ncxMapEnd())

        Dim dOpfID As Decimal = 1

        For Each sOPF As String In lOPF

            cfOPF.sbText.Append(cEPUB.opfManifestAdd("ID" & dOpfID.ToString().PadLeft(5, "0"), sOPF))
            dOpfID = dOpfID + 1
        Next

        cfOPF.sbText.Append(cEPUB.opfManifestEnd())


        cfOPF.sbText.Append(cEPUB.opfSpineStart())


        dOpfID = 1
        For Each sOPF As String In lOPF

            cfOPF.sbText.Append(cEPUB.opfSpineAdd("ID" & dOpfID.ToString().PadLeft(5, "0")))
            dOpfID = dOpfID + 1

        Next

        cfOPF.sbText.Append(cEPUB.opfSpineEnd())

        cfOPF.sbText.Append(cEPUB.opfGuid())

        cfOPF.sbText.Append(cEPUB.opfPackageEnd())



        System.IO.File.WriteAllText(cfMain.sPath, cfMain.sbText.ToString(), Encoding.UTF8)
        System.IO.File.WriteAllText(cfNav.sPath, cfNav.sbText.ToString(), Encoding.UTF8)
        System.IO.File.WriteAllText(cfNCX.sPath, cfNCX.sbText.ToString(), Encoding.UTF8)
        System.IO.File.WriteAllText(cfOPF.sPath, cfOPF.sbText.ToString(), Encoding.UTF8)



    End Sub

    Public Shared Function NewCharterMenu(ByVal sTitle As String) As cFile

        Dim sSectionID As String = AddSectionID().ToString().PadLeft(2, "0")
        Dim sSectionNM As String = "Section" & sSectionID
        dChapterID = 1

        CreateFolder(sOutPutPathEpub & sSectionNM)


        Dim sChapterMenuName As String = sFileNB & sSectionID & "_000.html"
        Dim sChapterMenuURL As String = sSectionNM & "/" & sChapterMenuName
        Dim sChapterMenuPath As String = sOutPutPathEpub & sSectionNM & "\" & sChapterMenuName
        Dim sChapterMenuTitle As String = sTitle

        NewCharterMenu = New cFile(sChapterMenuName, sChapterMenuURL, sChapterMenuPath, sChapterMenuTitle)

        NewCharterMenu.sbText.Append(htmlBodyStart2())
        NewCharterMenu.sbText.Append(htmlAddTitle(NewCharterMenu.sTitle))



        cfNav.sbText.Append(htmlAddBookList(NewCharterMenu.sTitle, NewCharterMenu.sTitle))


        cfNCX.sbText.Append(ncxNavPointAdd(NewCharterMenu.sTitle, NewCharterMenu.sTitle))


        lOPF.Add(NewCharterMenu.sURL)

    End Function

    Public Shared Function NewCharter(ByVal sTitle As String) As cFile


        Dim sSectionID As String = (dSectionID - 1).ToString().PadLeft(2, "0")
        Dim sSectionNM As String = "Section" & sSectionID
        Dim sChapterID As String = AddChapterID().ToString().PadLeft(3, "0")


        Dim sChapterName As String = sFileNB & sSectionID & "_" & sChapterID & ".html"
        Dim sChapterURL As String = sSectionNM & "/" & sChapterName
        Dim sChapterPath As String = sOutPutPathEpub & sSectionNM & "\" & sChapterName
        Dim sChapterTitle As String = sTitle
        NewCharter = New cFile(sChapterName, sChapterURL, sChapterPath, sChapterTitle)

        NewCharter.sbText.Append(htmlBodyStart2())
        NewCharter.sbText.Append(htmlAddTitle(NewCharter.sTitle))


        cfMain.sbText.Append(htmlAddBookList(NewCharter.sTitle, NewCharter.sURL))

        cfNav.sbText.Append(htmlAddBookListSub(NewCharter.sTitle, NewCharter.sURL))


        cfNCX.sbText.Append(ncxNavPointAdd(NewCharter.sTitle, NewCharter.sURL))
        cfNCX.sbText.Append(ncxNavPointEnd())

        lOPF.Add(NewCharter.sURL)
        cEPUB.CreateFolder(sOutPutPathEpub & sSectionNM & "\")


    End Function

    Public Shared Function NewAfterWord(ByVal sTitle As String) As cFile

        Dim sAfterWordName As String = "AfterWord" & AddAfterWordID().ToString() & ".html"
        Dim sAfterWordURL As String = sAfterWordName
        Dim sAfterWordPath As String = sOutPutPathEpub & sAfterWordName
        Dim sAfterWordTitle As String = sTitle


        NewAfterWord = New cFile(sAfterWordName, sAfterWordURL, sAfterWordPath, sAfterWordTitle)


        NewAfterWord.sbText.Append(htmlBodyStart1())
        NewAfterWord.sbText.Append(htmlAddTitle(NewAfterWord.sTitle))




        cfMain.sbText.Append(htmlAddBookList(NewAfterWord.sTitle, NewAfterWord.sURL))
        cfNav.sbText.Append(htmlAddBookList(NewAfterWord.sTitle, NewAfterWord.sURL))


        cfNCX.sbText.Append(ncxNavPointAdd(NewAfterWord.sTitle, NewAfterWord.sURL))
        cfNCX.sbText.Append(ncxNavPointEnd())

        lOPF.Add(NewAfterWord.sURL)


    End Function

    Public Shared Sub CreateFolder(ByVal sPath As String)

        If Not System.IO.Directory.Exists(sPath) Then

            System.IO.Directory.CreateDirectory(sPath)
        End If

    End Sub

#Region "html"

    Public Shared Function htmlBodyStart1() As String

        Dim sbText As New StringBuilder()

        sbText.Append("<?xml version='1.0' encoding='utf-8'?>")
        sbText.Append("<html xmlns=""http://www.w3.org/1999/xhtml"">")
        sbText.Append("<head>")
        sbText.Append("<title>")
        sbText.Append(sBookName)
        sbText.Append("</title>")
        sbText.Append("<meta http-equiv=""Content-Type"" content=""text/html; charset=utf-8""/>")
        sbText.Append("<link href=""stylesheet.css"" type=""text/css"" rel=""stylesheet""/>")
        sbText.Append("<link href=""page_styles.css"" type=""text/css"" rel=""stylesheet""/>")
        sbText.Append("</head>")
        sbText.Append("<body class=""mobiBody"">")
        htmlBodyStart1 = sbText.ToString()

    End Function

    Public Shared Function htmlBodyStart2() As String

        Dim sbText As New StringBuilder()

        sbText.Append("<?xml version='1.0' encoding='utf-8'?>")
        sbText.Append("<html xmlns=""http://www.w3.org/1999/xhtml"">")
        sbText.Append("<head>")
        sbText.Append("<title>")
        sbText.Append(sBookName)
        sbText.Append("</title>")
        sbText.Append("<meta http-equiv=""Content-Type"" content=""text/html; charset=utf-8""/>")
        sbText.Append("<link href=""../stylesheet.css"" type=""text/css"" rel=""stylesheet""/>")
        sbText.Append("<link href=""../page_styles.css"" type=""text/css"" rel=""stylesheet""/>")
        sbText.Append("</head>")
        sbText.Append("<body class=""mobiBody"">")
        htmlBodyStart2 = sbText.ToString()

    End Function

    Public Shared Function htmlBodyEnd() As String

        Dim sbText As New StringBuilder()
        sbText.Append("</body>")
        sbText.Append("</html>")

        htmlBodyEnd = sbText.ToString()

    End Function

    Public Shared Function htmlAddTitle(ByVal sText As String) As String

        Dim sbText As New StringBuilder()

        sbText.Append("<p class=""mobiTitle"">")
        sbText.Append(sText)
        sbText.Append("</p>")
        htmlAddTitle = sbText.ToString()

    End Function

    Public Shared Function htmlAddBookList(ByVal sName As String, ByVal sURL As String) As String

        Dim sbText As New StringBuilder()

        sbText.Append("<p class=""mobiList"">")
        sbText.Append("<a href=""" & sURL & """>")
        sbText.Append("<span class=""underline"">" & sName & "</span></a>")
        sbText.Append("</p>")
        htmlAddBookList = sbText.ToString()

    End Function

    Public Shared Function htmlAddBookListSub(ByVal sName As String, ByVal sURL As String) As String

        Dim sbText As New StringBuilder()
        sbText.Append("<blockquote class=""mobiList"">")
        sbText.Append("<p><a href=""" & sURL & """>")
        sbText.Append("<span class=""underline"">" & sName & "</span></a></p>")
        sbText.Append("</blockquote>")
        htmlAddBookListSub = sbText.ToString()

    End Function

    Public Shared Function htmlAddText(ByVal sText As String) As String

        Dim sbText As New StringBuilder()

        sbText.Append("<p class=""mobiText"">")
        sbText.Append(sText)
        sbText.Append("</p>")
        htmlAddText = sbText.ToString()

    End Function

#End Region

#Region "content.opf"

    Public Shared Function opfPackageStart() As String

        Dim sbText As New StringBuilder()

        sbText.Append("<?xml version='1.0' encoding='utf-8'?>")
        sbText.Append("<package xmlns=""http://www.idpf.org/2007/opf"" version=""2.0"" unique-identifier=""uuid_id"">")
        sbText.Append("<metadata xmlns:dc=""http://purl.org/dc/elements/1.1/"">")
        sbText.Append("<dc:language>" & sLang & "</dc:language>")
        sbText.Append("<dc:creator>" & sCreator & "</dc:creator>")
        sbText.Append("<dc:title>" & sBookName & "</dc:title>")
        sbText.Append("<meta name=""cover"" content=""idcover""/>")
        sbText.Append("<dc:identifier id=""uuid_id"">" & sGUID.ToString() & "</dc:identifier>")
        sbText.Append("</metadata>")
        opfPackageStart = sbText.ToString()

    End Function

    Public Shared Function opfPackageEnd() As String

        opfPackageEnd = "</package>"

    End Function

    Public Shared Function opfManifestStart() As String

        Dim sbText As New StringBuilder()

        sbText.Append("<manifest>")
        sbText.Append("<item href=""cover_image.jpg"" id=""idcover"" media-type=""image/jpeg""/>")
        sbText.Append("<item href=""Main.html"" id=""main"" media-type=""application/xhtml+xml""/>")
        opfManifestStart = sbText.ToString()

    End Function

    Public Shared Function opfManifestAdd(ByVal sID As String, ByVal sURL As String) As String

        Dim sbText As New StringBuilder()
        sbText.Append("<item href=""" & sURL & """ id=""" & sID & """ media-type=""application/xhtml+xml""/>")
        opfManifestAdd = sbText.ToString()

    End Function

    Public Shared Function opfManifestEnd() As String

        Dim sbText As New StringBuilder()
        sbText.Append("<item href=""Nav.html"" id=""nav"" media-type=""application/xhtml+xml""/>")
        sbText.Append("<item href=""page_styles.css"" id=""page_css"" media-type=""text/css""/>")
        sbText.Append("<item href=""stylesheet.css"" id=""css"" media-type=""text/css""/>")
        sbText.Append(" <item href=""titlepage.xhtml"" id=""titlepage"" media-type=""application/xhtml+xml""/>")
        sbText.Append("<item href=""toc.ncx"" media-type=""application/x-dtbncx+xml"" id=""ncx""/>")
        sbText.Append("</manifest>")
        opfManifestEnd = sbText.ToString()


    End Function

    Public Shared Function opfSpineStart() As String


        Dim sbText As New StringBuilder()
        sbText.Append("<spine toc=""ncx"">")
        sbText.Append("<itemref idref=""titlepage""/>")
        sbText.Append("<itemref idref=""main""/>")
        opfSpineStart = sbText.ToString()

    End Function

    Public Shared Function opfSpineAdd(ByVal sID As String) As String


        Dim sbText As New StringBuilder()
        sbText.Append("<itemref idref=""" & sID & """/>")
        opfSpineAdd = sbText.ToString()

    End Function

    Public Shared Function opfSpineEnd() As String

        opfSpineEnd = "</spine>"

    End Function

    Public Shared Function opfGuid() As String

        Dim sbText As New StringBuilder()
        sbText.Append("<guide>")
        sbText.Append("<reference href=""Nav.html"" type=""toc"" title=""Nav""/>")
        sbText.Append(" <reference href=""titlepage.xhtml"" type=""cover"" title=""Title Page""/>")
        sbText.Append("</guide>")
        opfGuid = sbText.ToString()
    End Function

#End Region

#Region "toc.ncx"

    Public Shared Function ncxMapStart() As String

        Dim sbText As New StringBuilder()

        sbText.Append("<?xml version='1.0' encoding='utf-8'?>")
        sbText.Append("<ncx xmlns=""http://www.daisy.org/z3986/2005/ncx/"" version=""2005-1"" xml:lang=""" & sLang & """>")
        sbText.Append("<head>")
        sbText.Append("<meta content=""" & sGUID & """ name=""dtb:uid""/>")
        sbText.Append("<meta content=""3"" name=""dtb:depth""/>")
        sbText.Append("</head>")
        sbText.Append("<docTitle>")
        sbText.Append("<text>toc</text>")
        sbText.Append("</docTitle>")
        sbText.Append("<navMap>")
        ncxMapStart = sbText.ToString()

    End Function

    Public Shared Function ncxMapEnd() As String

        ncxMapEnd = "</navMap></ncx>"

    End Function

    Public Shared Function ncxNavPointAdd(ByVal sText As String, ByVal sURL As String) As String

        Dim sbText As New StringBuilder()
        Dim dPlayId As Decimal = AddPlayID()
        sbText.Append("<navPoint class=""nav"" id=""ID_" & dPlayId.ToString().PadLeft(6, "0") & """ playOrder=""" & dPlayId & """>")
        sbText.Append("<navLabel>")
        sbText.Append("<text>" & sText & "</text>")
        sbText.Append("</navLabel>")
        sbText.Append("<content src=""" & sURL & """/>")
        ncxNavPointAdd = sbText.ToString()

    End Function

    Public Shared Function ncxNavPointEnd() As String
        ncxNavPointEnd = "</navPoint>"

    End Function

    Public Shared Function AddPlayID() As Decimal

        AddPlayID = dPlayID
        dPlayID = dPlayID + 1

    End Function

    Public Shared Function AddSectionID() As Decimal

        AddSectionID = dSectionID
        dSectionID = dSectionID + 1

    End Function

    Public Shared Function AddChapterID() As Decimal

        AddChapterID = dChapterID
        dChapterID = dChapterID + 1

    End Function

    Public Shared Function AddAfterWordID() As Decimal

        AddAfterWordID = dAfterWordID
        dAfterWordID = dAfterWordID + 1

    End Function

#End Region


End Class

Public Class cFile

    Sub New()
        sbText = New StringBuilder

    End Sub


    Sub New(ByVal _sFileName As String, ByVal _sURL As String, ByVal _sPath As String, ByVal _sTitle As String)

        sFileName = _sFileName
        sTitle = _sTitle
        sURL = _sURL
        sPath = _sPath
        sbText = New StringBuilder

    End Sub


    Sub New(ByVal _sFileName As String, ByVal _sURL As String, ByVal _sPath As String, ByVal _sTitle As String, ByVal _sSP1 As String)

        sFileName = _sFileName
        sTitle = _sTitle
        sURL = _sURL
        sPath = _sPath
        sSP1 = _sSP1
        sbText = New StringBuilder

    End Sub



    Sub New(ByVal _sFileName As String, ByVal _sURL As String, ByVal _sPath As String, ByVal _sTitle As String, ByVal _sSP1 As String, ByVal _sSP2 As String)

        sFileName = _sFileName
        sTitle = _sTitle
        sURL = _sURL
        sPath = _sPath
        sSP1 = _sSP1
        sSP2 = _sSP2
        sbText = New StringBuilder

    End Sub


    Private _sFileName As String

    Public Property sFileName As String
        Get
            Return _sFileName
        End Get
        Set(ByVal Value As String)
            _sFileName = Value
        End Set
    End Property



    Private _sbText As StringBuilder

    Public Property sbText As StringBuilder
        Get
            Return _sbText
        End Get
        Set(ByVal Value As StringBuilder)
            _sbText = Value
        End Set
    End Property



    Private _sTitle As String

    Public Property sTitle As String
        Get
            Return _sTitle
        End Get
        Set(ByVal Value As String)
            _sTitle = Value
        End Set
    End Property


    Private _sURL As String

    Public Property sURL As String
        Get
            Return _sURL
        End Get
        Set(ByVal Value As String)
            _sURL = Value
        End Set
    End Property


    Private _sPath As String
    Public Property sPath As String
        Get
            Return _sPath
        End Get
        Set(ByVal Value As String)
            _sPath = Value
        End Set
    End Property


    Private _sSP1 As String
    Public Property sSP1 As String
        Get
            Return _sSP1
        End Get
        Set(ByVal Value As String)
            _sSP1 = Value
        End Set
    End Property


    Private _sSP2 As String
    Public Property sSP2 As String
        Get
            Return _sSP2
        End Get
        Set(ByVal Value As String)
            _sSP2 = Value
        End Set
    End Property

End Class


